package cn.moonspace.flowerowner.httpclient;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.xml.sax.SAXException;

import cn.moonspace.common.util.ImgIdent;


public class SearchClient {
	
	private static Log log = LogFactory.getLog(SearchClient.class);
	
	protected HttpClient client;
	
	public SearchClient() {
		client = HttpClients.createDefault();
	}
	
	/**
	 * 通过官网查询违章信息
	 * 
	 * @param area			
	 * @param cardNumber
	 * @param cardType
	 * @param machineNo
	 * 
	 * example: SearchClient.searchRegulations("沪", "A6S359", "02/小型汽车号牌", "035546");
	 * 
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @throws SAXException 
	 */
	public static JSONObject searchRegulations(String area, String cardNumber, String cardType, String machineNo) throws ClientProtocolException, IOException, SAXException {
		HttpClient client = HttpClients.createDefault();
		RequestConfig config = RequestConfig.custom().setSocketTimeout(3000).setConnectTimeout(3000).build();
		HttpGet get = null;
		HttpPost post = null;
		HttpResponse response = null;
		
		// step 1 打开首页
		get = new HttpGet("http://www.shjtaq.com/Server1/dzjc_new.asp");
		get.setConfig(config);
		response = client.execute(get);
		String content = getStringResult(response.getEntity());
		String check = Jsoup.parse(content).getElementById("imgCode").attr("src");
		log.debug("验证码标签：" + check);
		get.releaseConnection();
		
		// step 2 获取首页验证码图片，并识别出验证码内容
		get = new HttpGet("http://www.shjtaq.com/Server1/" + check);
		get.setConfig(config);
		response = client.execute(get);
        BufferedImage iag = ImageIO.read(response.getEntity().getContent());
        ImgIdent imgIdent = new ImgIdent(iag);
        String validate = imgIdent.getValidatecode(4);
        log.debug("验证码识别：" + validate);
        get.releaseConnection();
        
        // step 3 提交查询表单
        post = new HttpPost("http://www.shjtaq.com/Server1/dzjc_new.asp");
        post.addHeader("Host", "www.shjtaq.com");
        post.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        post.addHeader("Accept-Language", "zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
        post.addHeader("Accept-Encoding", "gzip, deflate");
        post.addHeader("Referer", "http://www.shjtaq.com/Server1/dzjc_new.asp");
        post.addHeader("Connection", "keep-alive");
        
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("cardqz", area));
        nvps.add(new BasicNameValuePair("carnumber", cardNumber));
        nvps.add(new BasicNameValuePair("type1", cardType));
        nvps.add(new BasicNameValuePair("fdjh", machineNo));
        nvps.add(new BasicNameValuePair("verify", validate));
        nvps.add(new BasicNameValuePair("act", "search"));
        nvps.add(new BasicNameValuePair("WrongCode", ""));
        nvps.add(new BasicNameValuePair("submit", " 提 交 "));
        post.setEntity(new UrlEncodedFormEntity(nvps, "gb2312"));
        post.setConfig(config);
        HttpResponse res = client.execute(post);
        
        String resultHTML = new String(getStringResult(res.getEntity()).getBytes("ISO-8859-1"), "GB2312");
        post.releaseConnection();
        log.debug(resultHTML);

        JSONObject result = new JSONObject();
        JSONArray items = new JSONArray();
        
        if(resultHTML.contains("正在更新数据，请稍后访问，谢谢！")) {
        	result.put("error", "正在更新数据，请稍后访问，谢谢！");
        	return result;
        } else if(resultHTML.contains("系统正在更新当日电子警察数据，请稍后查询！")) {
        	result.put("error", "系统正在更新当日电子警察数据，请稍后查询！");
        	return result;
        } else if(resultHTML.contains("您输入的发动机编号有错误，请重新输入")) {
        	result.put("error", "您输入的发动机编号有错误！");
        	return result;
        } else {
        	// 解析具体内容
        	Document doc = Jsoup.parse(resultHTML);
    		List<Element> elements = doc.getElementsByClass("fontblack").last().getElementsByTag("table");
    		for(int i = 0;i < elements.size() - 2; i ++) {
    			
    			Element e = elements.get(i);
    			String text = e.text();
    			log.info(e.text());
    			if(text.contains("目前在本市没有") || text.contains("在外地没有")){
    				continue;
    			}
    			
    			List<Element> tdElement = e.getElementsByTag("td");
    			Element titleElement = tdElement.remove(0);	// 获取标题
    			// 删除无用信息
    			tdElement.remove(0);	
    			tdElement.remove(0);
    			tdElement.remove(0);
    			Element cardNumberElement = tdElement.remove(0);
    			tdElement.remove(0);
    			Element cardTypeElement = tdElement.remove(0);
    			tdElement.remove(tdElement.size()-1);

    			// 解析具体违规
    			JSONObject r = new JSONObject();
    			r.put("title", titleElement.text());
    			r.put("cardNumber", cardNumberElement.text().trim());
    			r.put("cardType", cardTypeElement.text().trim());
    			JSONArray array = new JSONArray();
    			for(int j = 0;j < tdElement.size(); j ++) {
    				Element element = tdElement.get(j);
    				switch(j % 19) {
    				case 0:array.add(new JSONObject());break; // 序号
    				case 1:break;
    				case 2:array.getJSONObject(j/19).put("time", element.text().trim());break; // 违法时间
    				case 3:break;
    				case 4:array.getJSONObject(j/19).put("seq", element.text().trim());break; // 凭证编号
    				case 5:break;
    				case 6:array.getJSONObject(j/19).put("dept", element.text().trim());break;	// 采集机关
    				case 7:break;
    				case 8:break;	// 发送机关
    				case 9:break;
    				case 10:array.getJSONObject(j/19).put("address", element.text().trim());break;	// 违法地点
    				case 11:break;
    				case 12:break;	// 裁决机关
    				case 13:break;
    				case 14:array.getJSONObject(j/19).put("content", element.text().trim());break;	// 违法内容
    				case 15:break;
    				case 16:array.getJSONObject(j/19).put("rule", element.text().trim());break;	// 违反条款
    				case 17:break;
    				case 18:array.getJSONObject(j/19).put("status", element.text().trim()); break;	// 状态
    				default:break;
    				}
    			}
    			r.put("count", array.size());
    			r.put("list", array);
	    		items.add(r);
    		}
    		if(items.size() == 0) {
    			result.put("error", "恭喜，没有违章信息");
    		} else {
    			result.put("result", items);
    		}
    		return result;
        }
	}
	
	/**
	 * 获取response中的结果
	 * 
	 * @param entity
	 * @return
	 * @throws IllegalStateException
	 * @throws IOException
	 */
	public static String getStringResult(HttpEntity entity) throws IllegalStateException, IOException {
        StringBuilder result = new StringBuilder();  
        if (entity != null) {  
            InputStream instream = entity.getContent();
            BufferedReader br = new BufferedReader(new InputStreamReader(instream, "ISO-8859-1"));  
            String temp = "";  
            while ((temp = br.readLine()) != null) {  
                result.append(temp);  
            }  
        }  
        return result.toString();
	}
	
	public static void main(String[] args) throws ClientProtocolException, IOException, SAXException {
		String area = "沪";
		String cardNumber = "A6S359";
		String cardType = "02/小型汽车号牌";
		String machineNo = "035546";
		JSONObject result = SearchClient.searchRegulations(area, cardNumber, cardType, machineNo);
		System.out.println(result);
	}
	
}
